package api

import (
	"a_plus_station/forms"
	"a_plus_station/global"
	"a_plus_station/middlewares"
	"a_plus_station/tables"
	vali_tran "a_plus_station/validator"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
)

// 创建订单
func OrderCreate(ctx *gin.Context) {
	var userIdInt int32
	token := ctx.Request.Header.Get("token")
	if token != "" {
		j := middlewares.NewJWT()
		// parseToken 解析token包含的信息
		claims, err := j.ParseToken(token)
		if err == nil {
			userIdInt = claims.ID
		}
	}

	var orderCreate forms.OrderCreate
	if err := ctx.ShouldBind(&orderCreate); err != nil {
		vali_tran.HandleValidatorError(ctx, err)
		return
	}

	form, err := ctx.MultipartForm()
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的多部分表单数据"})
		return
	}

	files := form.File["files"]
	if files == nil {
		files = []*multipart.FileHeader{} // 确保files不是nil
	}

	const uploadDir = "E:\\nginx-1.24.0\\html\\userFiles\\"

	// 只有当有文件需要处理时才创建目录
	if len(files) > 0 {
		if err := ensureDirExists(uploadDir); err != nil {
			ctx.JSON(http.StatusInternalServerError, gin.H{"error": "无法创建上传目录"})
			return
		}
	}

	var (
		errors      []string
		fileResults []map[string]interface{} // 存储每个文件处理结果的切片
	)

	for i, file := range files {
		// 处理单个文件并获取哈希值
		hash, status, err := processSingleFile(file, uploadDir)

		result := map[string]interface{}{
			"filename": file.Filename,
			"hash":     hash,
			"status":   status,
		}

		if err != nil {
			result["error"] = err.Error()
			errors = append(errors, fmt.Sprintf("文件 %d: %s (%s)", i+1, file.Filename, err.Error()))
		}

		fileResults = append(fileResults, result)
	}

	if len(errors) > 0 {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": errors})
		return
	}

	u1, err := uuid.NewUUID()
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
		return
	}
	fmt.Println(u1.String())

	newFileResults := make([]string, 0)
	for _, FM := range fileResults {
		newFileResults = append(newFileResults, FM["hash"].(string))
	}

	order := tables.Order{
		ID:              u1.String(),
		UserID:          userIdInt,
		Status:          0,
		OrderGoodsID:    orderCreate.GoodsID,
		Count:           0,
		Color:           "default",
		GoodsImage:      "default",
		GoodsName:       orderCreate.GoodsID,
		Platform:        "default",
		DistributorName: orderCreate.DistributorNumber,
		CustomerName:    orderCreate.Name,
		Email:           orderCreate.Email,
		Remark:          orderCreate.Remark,
		Files:           newFileResults,
	}

	tx := global.DB.Begin()
	result := tx.Create(&order) // 通过数据的指针来创建
	if result.Error != nil {
		//return nil,status.Errorf(codes.Internal,result.Error.Error()) // .Error()会帮我们转换成error
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": "用户注册失败",
		})
		tx.Rollback()
		return
	}
	tx.Commit()

	ctx.JSON(http.StatusOK, gin.H{
		"msg":    "创建成功",
		"status": 200,
	})
}

func ensureDirExists(dirPath string) error {
	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
		return os.MkdirAll(dirPath, 0755)
	}
	return nil
}

// 修改后的processSingleFile函数返回哈希值、状态和可能的错误
func processSingleFile(file *multipart.FileHeader, uploadDir string) (hashStr, status string, err error) {
	srcFile, err := file.Open()
	if err != nil {
		return "", "", fmt.Errorf("无法打开文件: %w", err)
	}
	defer srcFile.Close()

	// 计算文件哈希
	hash := sha256.New()
	if _, err := io.Copy(hash, srcFile); err != nil {
		return "", "", fmt.Errorf("计算哈希失败: %w", err)
	}
	hashStr = hex.EncodeToString(hash.Sum(nil))
	fileExt := filepath.Ext(file.Filename)
	newFilename := hashStr + fileExt
	filePath := filepath.Join(uploadDir, newFilename)

	// 检查文件是否已存在
	if fileExists(filePath) {
		return newFilename, "skipped", nil
	}

	// 重置文件指针并保存
	if _, err := srcFile.Seek(0, 0); err != nil {
		return newFilename, "", fmt.Errorf("重置文件指针失败: %w", err)
	}

	dstFile, err := os.Create(filePath)
	if err != nil {
		return newFilename, "", fmt.Errorf("创建文件失败: %w", err)
	}
	defer dstFile.Close()

	if _, err := io.Copy(dstFile, srcFile); err != nil {
		// 保存失败时删除部分写入的文件
		os.Remove(filePath)
		return newFilename, "", fmt.Errorf("保存文件失败: %w", err)
	}

	return newFilename, "saved", nil
}

func fileExists(filePath string) bool {
	_, err := os.Stat(filePath)
	return err == nil
}

//
//// 客户查询订单
//func OrderList(ctx *gin.Context) {
//	// 过滤条件
//	// 我的订单 - foodName status
//	pn := ctx.DefaultQuery("pageNum", "0")
//	pnint, _ := strconv.Atoi(pn)
//	pSize := ctx.DefaultQuery("pageSize", "10")
//	pSizeInt, _ := strconv.Atoi(pSize)
//	foodName := ctx.DefaultQuery("foodName", "")
//	status := ctx.DefaultQuery("status", "")
//
//	userInterface, _ := ctx.Get("userInfo")
//	userInfo := userInterface.(dto_out.UserInfo)
//
//	var order tables.Order
//	orderInfo, count, err := order.OrderList(ctx, userInfo.ID, foodName, status, pnint, pSizeInt)
//	if err != nil {
//		ctx.JSON(http.StatusUnauthorized, gin.H{
//			"msg": "查询订单失败",
//		})
//		return
//	}
//	fmt.Println(orderInfo, count)
//
//	if count == 0 {
//		ctx.JSON(http.StatusOK, gin.H{
//			"status": 200,
//			"data":   make([]string, 0),
//			"msg":    "创建分类成功",
//		})
//		return
//	} else {
//		var orI []dto_out.OrderInfo
//		for _, o := range orderInfo {
//			var orF []dto_out.OrderFoodInfo
//			for _, food := range o.OrderGoods {
//				rangeFood := dto_out.OrderFoodInfo{
//					ID:     food.ID,
//					Name:   food.FoodsName,
//					Price:  food.FoodsPrice,
//					Image:  food.FoodsImage,
//					Number: food.Nums,
//				}
//				orF = append(orF, rangeFood)
//			}
//			rangeOrder := dto_out.OrderInfo{
//				ID:       o.ID,
//				CreateAt: o.CreatedAt.Format("2006-01-02 15-04-05"),
//				Price:    o.Price,
//				Status:   o.Status,
//				Remark:   o.Remark,
//				Foods:    orF,
//			}
//			orI = append(orI, rangeOrder)
//		}
//
//		out := dto_out.OrderOut{
//			OrderInfo: orI,
//			Count:     count,
//		}
//		ctx.JSON(http.StatusOK, gin.H{
//			"status": 200,
//			"data":   out,
//			"msg":    "创建分类成功",
//		})
//	}
//
//}
//
//func OrderDesc(ctx *gin.Context) {
//	orderID := ctx.Param("id")
//	oId, _ := strconv.Atoi(orderID)
//	order := tables.Order{
//		BaseModel: tables.BaseModel{ID: int32(oId)},
//	}
//
//	result := global.DB.WithContext(ctx).Preload("OrderGoods").Find(&order)
//	if result.RowsAffected == 0 {
//		ctx.JSON(http.StatusBadRequest, gin.H{
//			"msg": "获取食物详情失败",
//		})
//		return
//	}
//
//	var orF []dto_out.OrderFoodInfo
//	for _, food := range order.OrderGoods {
//		rangeFood := dto_out.OrderFoodInfo{
//			ID:     food.ID,
//			Name:   food.FoodsName,
//			Price:  food.FoodsPrice,
//			Image:  food.FoodsImage,
//			Number: food.Nums,
//		}
//		orF = append(orF, rangeFood)
//	}
//	rangeOrder := dto_out.OrderInfo{
//		ID:       order.ID,
//		CreateAt: order.CreatedAt.Format("2006-01-02 15-04-05"),
//		Price:    order.Price,
//		Status:   order.Status,
//		Remark:   order.Remark,
//		Foods:    orF,
//	}
//
//	ctx.JSON(http.StatusOK, gin.H{
//		"status": 200,
//		"data":   rangeOrder,
//		"msg":    "创建分类成功",
//	})
//	return
//
//}
